package com.example.springframeworklearning.controller;

import com.example.springframeworklearning.domain.Order;
import com.example.springframeworklearning.enums.OrderStatus;
import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

/**
 * 组合 WebDataBinder 和 PropertyEditorRegistrar 来手动填充 bean 中的属性
 *
 * @author luo
 * @since 2022/9/19 16:53
 */
@RestController
public class BeanManipulationController {

    private final PropertyEditorRegistrar propertyEditorRegistrar;

    private final ConversionService conversionService;

    public BeanManipulationController(PropertyEditorRegistrar propertyEditorRegistrar, @Qualifier("converterService") ConversionService conversionService) {
        this.propertyEditorRegistrar = propertyEditorRegistrar;
        this.conversionService = conversionService;
    }

    /**
     * 一、使用 PropertyEditorRegistrar 来配置 bean 中属性的编辑
     * 使用 PropertyEditorRegistrar 接口可以很轻易的将其与 WebDataBinder 对象连接到一起
     *
     * @param webDataBinder
     */
    @InitBinder
    void data(WebDataBinder webDataBinder) {
        propertyEditorRegistrar.registerCustomEditors(webDataBinder);
    }

    /**
     * 访问 http://localhost:8084/list?createTime=20220912
     *
     * @param order
     * @return
     */
    @GetMapping("/list")
    public String list(Order order) {
        return order.getCreateTime() + "你好";
    }


    /**
     * 二、使用 Converter 来实现 字符串到 枚举的转换
     * 注意：此请求需要发送 http://localhost:8084/orderStatusEnumConvert?orderStatus=PAID
     * 才能访问成功
     * 如果要自定义枚举字符串的内容需要修改
     * com.example.springframeworklearning.converter.StringOrderStatusConverterFactory.StringToEnumConverter#convert(java.lang.String) 的实现
     *
     * @param orderStatus
     * @return
     */
    @GetMapping("/orderStatusEnumConvert")
    public String orderStatusEnumConvert(@RequestParam OrderStatus orderStatus) {
        return "解析到的订单状态是：" + orderStatus;
    }


    /**
     * 在应用中使用 配置好的 ConversionService 来转换数据类型
     * @return
     */
    @GetMapping("/testConversionService")
    public LinkedList<String> testConversionService() {
        List<Integer> input = Arrays.asList(1, 2, 3, 4);

        @SuppressWarnings("unchecked")
        LinkedList<String> convert = (LinkedList<String>) conversionService.convert(
//                指定输入的数据源
                input,
//                指定数据源的类型
                TypeDescriptor.forObject(input),
//                指定 最终输出的数据类型
                TypeDescriptor.collection(LinkedList.class, TypeDescriptor.valueOf(String.class))
        );

        return convert;
    }

}
